from enum import Flag
from msilib.schema import Error
import re
import pandas as pd
from  chinese_calendar  import is_holiday
import datetime
import numpy as np
from numpy import flatiter, left_shift, nan

def REF(list_,window):
    return(pd.Series(list_).shift(window).to_list())
            
def MA(list_,window):
    return pd.Series(list_).rolling(window).mean().to_list()

def LLV(list_,window):
    return pd.Series(list_).rolling(window).min().to_list()

def HHV(list_,window):
    return pd.Series(list_).rolling(window).max().to_list()

def EMA(list_,N):
    """
    若Yn=EMA(Xn，N)，则Yn=[2*Xn+(N-1)*Yn-1]/(N+1)，其中Yn-1表示上一周期的Y值。
    """
    ema_=[]
    for i in range(len(list_)):
        if i==0:
            ema_.append(list_[0])    
        elif np.isnan(list_[i]) or np.isnan(ema_[-1]):
            ema_.append(list_[i])
        else:
            ema_.append(2*list_[i]/(N+1)+(N-1)/(N+1)*ema_[-1])
    return ema_

def EXPMA(CLOSE,N):#EMA指数平均数指标
    return EMA(CLOSE,N)

def SMA(list_,N,M):
    """
    #
    SMA(X，N，M) X的N日累积平均，M为权重
    如Y=(XM+Y(N-M))/N
    """
    sma_=[]
    for i in range(len(list_)):
        if i==0:
            sma_.append(list_[0])    
        elif np.isnan(list_[i]) or np.isnan(sma_[-1]):
            sma_.append(list_[i])
        else:
            sma_.append((M*list_[i]+(N-M)*sma_[-1])/N)
    return sma_

def ADD(list_,x):
    if isinstance(x,(float,int)):
        return [i+x for i in list_]
    elif type(x)==list and len(list_)==len(x):
        return [i+j for i,j in zip(list_,x)]

def ADDS(*args):
    exist_list=0
    _arg_len=[]
    for arg in args:
        if type(arg)==list:
            _arg_len.append(len(arg))
            exist_list=1
    if  max(_arg_len)!=min(_arg_len):
        print("list length must equal")
        raise ValueError
    arg_len=max(_arg_len)
    if exist_list==0:
        result=0
        for arg in args:
            result+=arg
        return result
    else:
        result=[0]*arg_len
        for arg in args:
            if isinstance(arg,(float,int)):
                for i in range(arg_len):
                    result[i]+=arg
            elif isinstance(arg,list):
                for index,val in enumerate(arg):
                    result[index]+=val
            else:
                print("args exist must be list,float,int")
                raise TypeError
        return result

        

def subtraction(list_,x):
    if isinstance(x,(float,int)):
        return [i-x for i in list_]
    elif type(x)==list and len(list_)==len(x):
        return [i-j for i,j in zip(list_,x)]

def multiply(list_,x):
    if isinstance(x,(float,int)):
        return [i*x for i in list_]
    elif type(x)==list and len(list_)==len(x):
        return [i*j for i,j in zip(list_,x)]

def divide(list_,x):
    if isinstance(x,(float,int)):
        if x==0:
            raise ZeroDivisionError
        else:
            return [i/x for i in list_]
    elif type(x)==list and len(list_)==len(x):
        return [i/j if j!=0 else nan for i,j in zip(list_,x)]

def MAX(list_,x):
    if isinstance(x,(float,int)):
        return [max(i,x) for i in list_]
    elif type(x)==list and len(list_)==len(x):
        return [max(i,j) for i,j in zip(list_,x)]   

def ABS(list_):
    return [abs(i) for i in list_]

def CROSS(x,list_):
    li=[]
    if isinstance(x,(float,int)):
        for i in range(len(list_)):
            if i<len(list_)-1:#防止报list_1[i+1]超出索引
                li.append(x<=list_[i] and x>=list_[i+1])
            else:
                li.append(x==list_[-1])
        return li
    elif type(x)==list and len(list_)==len(x):
        for i in range(len(list_)):
            if i<len(list_)-1:#防止报list_1[i+1]超出索引
                li.append(x[i]<=list_[i] and x[i+1]>=list_[i+1])
            else: #此时i已为len(list_)
                li.append(x[i]==list_[i])
        return li

def n_days_before(st_day,n):
    """
    st_day:开始日期
    :type st_day: datetime.date | datetime.datetime
    """
    while(n>0):
        if not is_holiday(st_day):
            n=n-1
        st_day=st_day-datetime.timedelta(1)
    return st_day

def STD(S,N):             #求序列的N日标准差，返回序列    
    return  pd.Series(S).rolling(N).std(ddof=0).to_list()

def TFILTER(BUY,SELL,N): #用法:TFILTER(买入条件,卖出条件,N);过滤掉买入(卖出)信号发出后,下一个反向信号发出前的所有买入(卖出)信号,
                        # N=1表示仅对买入信号过滤;
                        # N=2表示仅对卖出信号过滤;
                        # N=0表示对买入和卖出信号都过滤,返回1,2表示买入或卖出条件成立;
                        # 同一K线上只能有一个信号;
    res=[]
    #先找到买信号，再找到卖信号，如果重复，买信号为0，无效，买卖信号中间出现的买信号为0
    for i in range(len(BUY)):
        if BUY[i] and SELL[i]:
            BUY[i]=0
            SELL[i]=0
    if N==1:#buy filter
        buy_index=0
        while(buy_index<len(BUY)):
            buy=BUY[buy_index]
            if buy:
                res.append(1)
                i=buy_index
                while((not SELL[i]) and i<len(SELL)-1):
                    res.append(0)
                    i+=1
                buy_index=i+1
            else:
                buy_index+=1
                res.append(0)
    if N==2:#sell filter
        sell_index=0
        while(sell_index<len(SELL)):
            sell=SELL[sell_index]
            if sell:
                res.append(1)
                i=sell_index
                while((not BUY[i]) and i<len(SELL)-1):
                    res.append(0)
                    i+=1
                sell_index=i+1
            else:
                sell_index+=1
                res.append(0)
    if N==0: #返回1/2表示买入/卖出条件成立
        res_buy=[]
        buy_index=0
        while(buy_index<len(BUY)):
            buy=BUY[buy_index]
            if buy:
                res_buy.append(1)
                i=buy_index
                while((not SELL[i]) and i<len(SELL)-1):
                    res_buy.append(0)
                    i+=1
                buy_index=i+1
            else:
                buy_index+=1
                res_buy.append(0)

        res_sell=[]
        sell_index=0
        while(sell_index<len(SELL)):
            sell=SELL[sell_index]
            if sell:
                res_sell.append(2)
                i=sell_index
                while((not BUY[i]) and i<len(SELL)-1):
                    res_sell.append(0)
                    i+=1
                sell_index=i+1
            else:
                sell_index+=1
                res_sell.append(0)
        for i in range(len(BUY)):
            if res_buy[i]:
                res.append(res_buy[i])
            elif res_sell[i]:
                res.append(res_sell[i])
            else:
                res.append(0)
    return res

if __name__=='__main__':
#    a=(ADDS([1,2,3],[4,25,4],[12,2,5]))
#    print(STD(a,2))
   buy =[1,1,0,1,0,1,1,0]
   sell=[0,0,1,1,1,0,1,1]
   print(TFILTER(buy,sell,0))